package registnet.base.source;

import java.util.List;
import java.util.ListIterator;

import registnet.base.Checklist;
import registnet.base.CourseTaken;
import registnet.base.CourseWork;
import registnet.base.DefaultPlanOfCourseWork;
import registnet.base.IChecklist;
import registnet.base.ICourse;
import registnet.base.Transcript;

/**
 * Defines a class for creating a <code>Checklist</code> from the data from the database.
 */
public class ChecklistSource implements IChecklistSource {

	/**
	 * The checklist.
	 */
	private Checklist checklist;
	
	/**
	 * The student number of the student associated to the checklist.
	 */
	private String studentNumber;
	
	/**
	 * Creates a new checklist for a student with the given student number.
	 * @param studentNumber
	 */
	public ChecklistSource(String studentNumber){
		this.studentNumber = studentNumber;
		load();
	}
	
	@Override
	public IChecklist getChecklist() {
		return checklist;
	}

	@Override
	public IChecklist load() {
		
		if (checklist != null) return checklist;
		else checklist = new Checklist();
		
		try{
			//studentNumber
			checklist.setStudentNumber(studentNumber);
			
			//planOfCourseWork
			DefaultPlanOfCourseWork planOfCourseWork = (DefaultPlanOfCourseWork)(new PlanOfCourseWorkSource(studentNumber).getPlanOfCourseWork());
			checklist.setPlanOfCourseWork(planOfCourseWork);
			
			//transcript
			Transcript transcript = (Transcript)(new TranscriptSource(studentNumber).getTranscript());
			transcript.setCurriculum(planOfCourseWork.getCurriculum());
			checklist.setTranscript(transcript);
			
			//courses
			List<ICourse> curriculumCourses = transcript.getCurriculum().getAllCourses();
			for(int i=0; i<curriculumCourses.size(); i++){
				ICourse course = curriculumCourses.get(i);
				ICourse tmpCourse = null;
				
				//incorporate planOfCourseWork
				try{
					tmpCourse = (CourseWork)checkPlanOfCourseWork(course.getCourseCode(), course.getYear(), course.getSemester());
				}catch(NullPointerException e){ }
				if(tmpCourse!=null) course = tmpCourse;
				
				//incorporate transcript
				tmpCourse = null;
				try{
					tmpCourse = (CourseTaken)transcript.getRecentCourseTaken(course.getCourseCode());
				}catch(NullPointerException e){ }	
				if(tmpCourse!=null){
					tmpCourse.setSemester(course.getSemester());
					tmpCourse.setYear(course.getYear());
					course = tmpCourse;
				}
				
				checklist.addCourse(course);
			}
			
		}catch(Exception e){
			System.err.println("****[error] Checklist loading failed. "+e.getMessage());
		}
		
		return checklist;
	}

	/**
	 * Retrieve from plan of coursework the coursework with the given course code, for the given semester and year.
	 * @param courseCode
	 * @param year
	 * @param semester
	 * @return the coursework with the given course code, for the given semester and year
	 */
	private ICourse checkPlanOfCourseWork(String courseCode, int year, int semester){
		if(courseCode.equals("GE(AH)")){
			ListIterator<ICourse> li = checklist.getPlanOfCourseWork().getGECourses("AH", year, semester).listIterator();
			while(li.hasNext()){
				ICourse course = li.next();
				if(checklist.contains(course.getCourseCode())) continue;
				else return course;
			}
		}else if(courseCode.equals("GE(SSP)")){
			ListIterator<ICourse> li = checklist.getPlanOfCourseWork().getGECourses("SSP", year, semester).listIterator();
			while(li.hasNext()){
				ICourse course = li.next();
				if(checklist.contains(course.getCourseCode())) continue;
				else return course;
			}
		}else if(courseCode.equals("GE(MST)")){
			ListIterator<ICourse> li = checklist.getPlanOfCourseWork().getGECourses("MST", year, semester).listIterator();
			while(li.hasNext()){
				ICourse course = li.next();
				if(checklist.contains(course.getCourseCode())) continue;
				else return course;
			}
		}else if(courseCode.equals("ELECTIVE")){
			ListIterator<ICourse> li = checklist.getPlanOfCourseWork().getCourses("ELECTIVE", year, semester).listIterator();
			while(li.hasNext()){
				ICourse course = li.next();
				if(checklist.contains(course.getCourseCode())) continue;
				else return course;
			}
		}else if(courseCode.equals("PE 2")){
			ListIterator<ICourse> li = checklist.getPlanOfCourseWork().getCourses("PE 2", year, semester).listIterator();
			while(li.hasNext()){
				ICourse course = li.next();
				if(checklist.contains(course.getCourseCode())) continue;
				else return course;
			}
		}else if(courseCode.equals("MAJOR")){
			ListIterator<ICourse> li = checklist.getPlanOfCourseWork().getCourses("MAJOR", year, semester).listIterator();
			while(li.hasNext()){
				ICourse course = li.next();
				if(checklist.contains(course.getCourseCode())) continue;
				else return course;
			}
		}else if(courseCode.equals("NSTP 1")){
			ListIterator<ICourse> li = checklist.getPlanOfCourseWork().getCourses("NSTP 1", year, semester).listIterator();
			while(li.hasNext()){
				ICourse course = li.next();
				if(checklist.contains(course.getCourseCode())) continue;
				else return course;
			}
		}else if(courseCode.equals("NSTP 2")){
			ListIterator<ICourse> li = checklist.getPlanOfCourseWork().getCourses("NSTP 2", year, semester).listIterator();
			while(li.hasNext()){
				ICourse course = li.next();
				if(checklist.contains(course.getCourseCode())) continue;
				else return course;
			}
		}else if(courseCode.equals("CMSCCOURSE")){
			ListIterator<ICourse> li = checklist.getPlanOfCourseWork().getCourses("CMSCCOURSE", year, semester).listIterator();
			while(li.hasNext()){
				ICourse course = li.next();
				if(checklist.contains(course.getCourseCode())) continue;
				else return course;
			}
		}else if(courseCode.equals("COGNATE")){
			ListIterator<ICourse> li = checklist.getPlanOfCourseWork().getCourses("COGNATE", year, semester).listIterator();
			while(li.hasNext()){
				ICourse course = li.next();
				if(checklist.contains(course.getCourseCode())) continue;
				else return course;
			}
		}else if(courseCode.equals("OPTION")){
			ListIterator<ICourse> li = checklist.getPlanOfCourseWork().getCourses("OPTION", year, semester).listIterator();
			while(li.hasNext()){
				ICourse course = li.next();
				if(checklist.contains(course.getCourseCode())) continue;
				else return course;
			}
		}else if(courseCode.equals("OPTION6")){
			ListIterator<ICourse> li = checklist.getPlanOfCourseWork().getCourses("OPTION6", year, semester).listIterator();
			while(li.hasNext()){
				ICourse course = li.next();
				if(checklist.contains(course.getCourseCode())) continue;
				else return course;
			}
		}else if(courseCode.equals("SEMINAR")){
			ListIterator<ICourse> li = checklist.getPlanOfCourseWork().getCourses("SEMINAR", year, semester).listIterator();
			while(li.hasNext()){
				ICourse course = li.next();
				if(checklist.contains(course.getCourseCode())) continue;
				else return course;
			}
		}else if(courseCode.equals("SPECIALIZED")){
			ListIterator<ICourse> li = checklist.getPlanOfCourseWork().getCourses("SPECIALIZED", year, semester).listIterator();
			while(li.hasNext()){
				ICourse course = li.next();
				if(checklist.contains(course.getCourseCode())) continue;
				else return course;
			}
		}else if(courseCode.equals("SUPPORTIVE")){
			ListIterator<ICourse> li = checklist.getPlanOfCourseWork().getCourses("SUPPORTIVE", year, semester).listIterator();
			while(li.hasNext()){
				ICourse course = li.next();
				if(checklist.contains(course.getCourseCode())) continue;
				else return course;
			}
		}else if(courseCode.equals("TECHNICAL")){
			ListIterator<ICourse> li = checklist.getPlanOfCourseWork().getCourses("TECHNICAL", year, semester).listIterator();
			while(li.hasNext()){
				ICourse course = li.next();
				if(checklist.contains(course.getCourseCode())) continue;
				else return course;
			}
		}else if(courseCode.equals("THESIS")){
			ListIterator<ICourse> li = checklist.getPlanOfCourseWork().getCourses("THESIS", year, semester).listIterator();
			while(li.hasNext()){
				ICourse course = li.next();
				if(checklist.contains(course.getCourseCode())) continue;
				else return course;
			}
		}else if(courseCode.equals("PRACTICUM")){
			ListIterator<ICourse> li = checklist.getPlanOfCourseWork().getCourses("PRACTICUM", year, semester).listIterator();
			while(li.hasNext()){
				ICourse course = li.next();
				if(checklist.contains(course.getCourseCode())) continue;
				else return course;
			}
		}
		return null;
	}
	
}
